﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections.ObjectModel;
using System.Drawing;

namespace Tzeentch
{
    class Polygon: ICloneable
    {
        #region Properties
        /// <summary>
        /// Gets or sets the corners of the Polygon.
        /// </summary>
        /// <value>
        /// The corners.
        /// </value>
        /// TODO? probably should be list (like it matters in .net)
        public Point[] Corners { get; set; }

        /// <summary>
        /// Gets the center of the Polygon.
        /// </summary>
        public Point Center
        {
            get
            {
                //returns the center of the polygon
                //TODO: implement
                return new Point(0, 0);
            }
        }

        /// <summary>
        /// Gets or sets the color.
        /// </summary>
        /// <value>
        /// The color.
        /// </value>
        public Color Color{ get; set; }
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="Polygon"/> class.
        /// </summary>
        /// <param name="maxX">The max X.</param>
        /// <param name="maxY">The max Y.</param>
        public Polygon(int maxX,int maxY,Random rand)
        {            
            Corners = new Point[3];
            for (int i = 0; i < 3; i++)
            {
                Corners[i].X = rand.Next(maxX);
                Corners[i].Y = rand.Next(maxY);
            }
            Color =  Color.FromArgb(
                255,
                rand.Next(255),
                rand.Next(255),
                rand.Next(255));

        }

        public Polygon()
        {

        }
        #endregion

        #region ICloneable Members

        /// <summary>
        /// Creates a new object that is a copy of the current instance.
        /// </summary>
        /// <returns>
        /// A new object that is a copy of this instance.
        /// </returns>
        public object Clone()
        {
            return new Polygon()
            {
                Color = this.Color,
                Corners = (Point[])this.Corners.Clone()
            };
        }

        #endregion

        #region Methods

        /// <summary>
        /// Mutate the polygon by moving one of the corners. Checks bounds of a picture, but won't check whether min<=max.
        /// </summary>
        /// <param name="minMove">Minimal move in x and y (positive).</param>
        /// <param name="maxMove">Maximal move in x and y (positive).</param>
        /// <param name="width">Width of a picture.</param>
        /// <param name="height">Height of a picture.</param>
        /// <param name="rand">Random generator.</param>
        public void MutateMoveOneCorner(int minMove, int maxMove, int width, int height, Random rand)
        {
            // take one corner...
            int cornersIndex = rand.Next(Corners.Length);
            int x = Corners[cornersIndex].X;
            int y = Corners[cornersIndex].Y;
            // random move
            int moveX = rand.Next(minMove, maxMove);
            int moveY = rand.Next(minMove, maxMove);
            // move to the left/top or right/down
            if (rand.Next(-1, 1) < 0) moveX *= -1;
            if (rand.Next(-1, 1) < 0) moveY *= -1;
            // I like to move it move it
            x += moveX;
            y += moveY;
            // check the bounds
            if (x < 0) x = 0;
            if (x >= width) x = width - 1;
            if (y < 0) y = 0;
            if (y >= height) y = height - 1;
            Corners[cornersIndex].X = x;
            Corners[cornersIndex].Y = y;
        }

        /// <summary>
        /// Mutate the polygon by changing the color of polygon.
        /// </summary>
        /// <param name="minRDiff">Minimal red color change.</param>
        /// <param name="maxRDiff">Maximal red color change.</param>
        /// <param name="minGDiff">Minimal green color change.</param>
        /// <param name="maxGDiff">Maximal green color change.</param>
        /// <param name="minBDiff">Minimal blue color change.</param>
        /// <param name="maxBDiff">Maximal blue color change.</param>
        /// <param name="rand">Random generator.</param>
        public void MutateChangeColor(int minColorDiff, int maxColorDiff, Random rand)
        {
            int newR, newG, newB;
            // let's change 'em
            newR = Color.R + rand.Next(minColorDiff, maxColorDiff);
            newG = Color.G + rand.Next(minColorDiff, maxColorDiff);
            newB = Color.B + rand.Next(minColorDiff, maxColorDiff);
            // check bounds
            if (newR < 0) newR = 0; else if (newR > 255) newR = 255;
            if (newG < 0) newG = 0; else if (newG > 255) newG = 255;
            if (newB < 0) newB = 0; else if (newB > 255) newB = 255;
            // set new values
            Color = Color.FromArgb(255, newR, newG, newB);
        }

        #endregion
    }
}
